ESP32-Bluetooth

技术经验 dingxiao 阅读数:4177 2019年5月18日 13:01

ESP32-Bluetooth

0x01-ESP32 BLE测试
  • ESP32自带蓝牙模块,好爽的感觉,测试开始。

  • 运行自带BLE_uart的demo。

 #include "BLEDevice.h"
 #include "BLEServer.h"
 #include "BLEUtils.h"
 #include "BLE2902.h"
 
 BLEServer *pServer = NULL;
 BLECharacteristic * pTxCharacteristic;
 BLECharacteristic * pCharacteristic;
 bool deviceConnected = false;
 bool oldDeviceConnected = false;
 uint8_t txValue = 0;
 
 // See the following for generating UUIDs:
 // https://www.uuidgenerator.net/
 
 #define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
 #define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
 #define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
 
 //#define SERVICE_UUID           "025A7775-49AA-42BD-BBDB-E2AE77782966" // Black Widow BLE
 //#define CHARACTERISTIC_UUID_RX "A9CD2F86-8661-4EB1-B132-367A3434BC90"
 //#define CHARACTERISTIC_UUID_TX "F38A2C23-BC54-40FC-BED0-60EDDA139F47"
 
 
 //#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
 //#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
 
 
 class MyServerCallbacks: public BLEServerCallbacks {
     void onConnect(BLEServer* pServer) {
       deviceConnected = true;
     };
 
     void onDisconnect(BLEServer* pServer) {
       deviceConnected = false;
     }
 };
 
 class MyCallbacks: public BLECharacteristicCallbacks {
   
     void onWrite(BLECharacteristic *pCharacteristic) {
       std::string rxValue = pCharacteristic->getValue();
                             
 
 //      Serial.println("DXDXDX");
 
       if (rxValue.length() > 0) {
         Serial.println("*********");
         Serial.print("Received Value: ");
         for (int i = 0; i < rxValue.length(); i++)
           Serial.print(rxValue[i]);
 
         Serial.println();
         Serial.println("*********");
       }
 
       if(rxValue == "ON")
       {
         Serial.println("Turning ON the led");
         digitalWrite(LED_BUILTIN,HIGH);
       }
       if(rxValue == "OFF")
       {
         Serial.println("Turning OFF the led");
         digitalWrite(LED_BUILTIN,LOW);
       }
     }
 };
 
 
 void setup() {
   Serial.begin(115200);
 
   pinMode(LED_BUILTIN,OUTPUT);
 
   // Create the BLE Device
   BLEDevice::init("DX-LED");
 
   // Create the BLE Server
   pServer = BLEDevice::createServer();
   pServer->setCallbacks(new MyServerCallbacks());
 
   // Create the BLE Service
   BLEService *pService = pServer->createService(SERVICE_UUID);
 
   // Create a BLE Characteristic
   pTxCharacteristic = pService->createCharacteristic(
           CHARACTERISTIC_UUID_TX,
           BLECharacteristic::PROPERTY_NOTIFY
          );
                       
   pTxCharacteristic->addDescriptor(new BLE2902());
 
   BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
             CHARACTERISTIC_UUID_RX,
            BLECharacteristic::PROPERTY_WRITE
                      | BLECharacteristic::PROPERTY_WRITE_NR
           );
   pRxCharacteristic->setReadProperty(true);
   pRxCharacteristic->setWriteProperty(true);
   pRxCharacteristic->setCallbacks(new MyCallbacks());
 
 
 //  pCharacteristic = pService->createCharacteristic(
 //                      CHARACTERISTIC_UUID,
 //                      BLECharacteristic::PROPERTY_READ   |
 //                      BLECharacteristic::PROPERTY_WRITE  |
 //                      BLECharacteristic::PROPERTY_NOTIFY |
 //                      BLECharacteristic::PROPERTY_INDICATE
 //                    );
 //  pCharacteristic->addDescriptor(new BLE2902());
 //  pCharacteristic->setReadProperty(true);
 //  pCharacteristic->setWriteProperty(true);
 //  pCharacteristic->setCallbacks(new MyCallbacks());
 
 
   // Start the service
   pService->start();
 
   // Start advertising
   pServer->getAdvertising()->start();
   Serial.println("Waiting a client connection to notify...");
 }
 
 void loop() {
 
     if (deviceConnected) {
         pCharacteristic->setValue(&txValue, 1);
         pCharacteristic->notify();
         txValue++;
   delay(100); // bluetooth stack will go into congestion, if too many packets are sent
  }
 
     // disconnecting
     if (!deviceConnected && oldDeviceConnected) {
         delay(500); // give the bluetooth stack the chance to get things ready
         pServer->startAdvertising(); // restart advertising
         Serial.println("start advertising");
         oldDeviceConnected = deviceConnected;
     }
     // connecting
     if (deviceConnected && !oldDeviceConnected) {
   // do stuff here on connecting
         oldDeviceConnected = deviceConnected;
     }
 }
  • 其中UUID是BLE协议规定的服务标识号,注明了服务提供的数据接口。

 //#define SERVICE_UUID           "025A7775-49AA-42BD-BBDB-E2AE77782966" // Black Widow BLE
 //#define CHARACTERISTIC_UUID_RX "A9CD2F86-8661-4EB1-B132-367A3434BC90"
 //#define CHARACTERISTIC_UUID_TX "F38A2C23-BC54-40FC-BED0-60EDDA139F47"

0x02-移动端Flutter控制Bluetooth
  • Flutter作为一个跨平台应用框架,提供了对ios及android平台的Bluetooth的支持。

  • 简单的操作代码-main.dart为:

 // Copyright 2017, Paul DeMarco.
 // All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_blue/flutter_blue.dart';
 import 'package:flutter_blue_example/widgets.dart';
 
 void main() {
   runApp(new FlutterBlueApp());
 }
 
 class FlutterBlueApp extends StatefulWidget {
   FlutterBlueApp({Key key, this.title}) : super(key: key);
 
   final String title;
 
   @override
   _FlutterBlueAppState createState() => new _FlutterBlueAppState();
 }
 
 class _FlutterBlueAppState extends State<FlutterBlueApp> {
   FlutterBlue _flutterBlue = FlutterBlue.instance;
 
   /// Scanning
   StreamSubscription _scanSubscription;
   Map<DeviceIdentifier, ScanResult> scanResults = new Map();
   bool isScanning = false;
 
   /// State
   StreamSubscription _stateSubscription;
   BluetoothState state = BluetoothState.unknown;
 
   /// Device
   BluetoothDevice device;
   bool get isConnected => (device != null);
   StreamSubscription deviceConnection;
   StreamSubscription deviceStateSubscription;
   List<BluetoothService> services = new List();
   Map<Guid, StreamSubscription> valueChangedSubscriptions = {};
   BluetoothDeviceState deviceState = BluetoothDeviceState.disconnected;
 
   @override
   void initState() {
     super.initState();
     // Immediately get the state of FlutterBlue
     _flutterBlue.state.then((s) {
       setState(() {
         state = s;
       });
     });
     // Subscribe to state changes
     _stateSubscription = _flutterBlue.onStateChanged().listen((s) {
       setState(() {
         state = s;
       });
     });
   }
 
   @override
   void dispose() {
     _stateSubscription?.cancel();
     _stateSubscription = null;
     _scanSubscription?.cancel();
     _scanSubscription = null;
     deviceConnection?.cancel();
     deviceConnection = null;
     super.dispose();
   }
 
   @override
   Widget build(BuildContext context) {
     var tiles = new List<Widget>();
     if (state != BluetoothState.on) {
       tiles.add(_buildAlertTile());
     }
     if (isConnected) {
       tiles.add(_buildDeviceStateTile());
       tiles.addAll(_buildServiceTiles());
     } else {
       tiles.addAll(_buildScanResultTiles());
     }
     return new MaterialApp(
       home: new Scaffold(
         appBar: new AppBar(
           title: const Text('FlutterBlue'),
           actions: _buildActionButtons(),
         ),
         floatingActionButton: _buildScanningButton(),
         body: new Stack(
           children: <Widget>[
             (isScanning) ? _buildProgressBarTile() : new Container(),
             new ListView(
               children: tiles,
             )
           ],
         ),
       ),
     );
   }
 }
...

 
  • widgets.dart为:

 // Copyright 2017, Paul DeMarco.
 // All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:flutter/material.dart';
 import 'package:flutter_blue/flutter_blue.dart';
 
 class ScanResultTile extends StatelessWidget {
   const ScanResultTile({Key key, this.result, this.onTap}) : super(key: key);
 
   final ScanResult result;
   final VoidCallback onTap;
 
   Widget _buildTitle(BuildContext context) {
     if (result.device.name.length > 0) {
       return Column(
         mainAxisAlignment: MainAxisAlignment.start,
         crossAxisAlignment: CrossAxisAlignment.start,
         children: <Widget>[
           Text(result.device.name),
           Text(
             result.device.id.toString(),
             style: Theme.of(context).textTheme.caption,
           )
         ],
       );
     } else {
       return Text(result.device.id.toString());
     }
   }
 
   Widget _buildAdvRow(BuildContext context, String title, String value) {
     return Padding(
       padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
       child: Row(
         crossAxisAlignment: CrossAxisAlignment.start,
         children: <Widget>[
           Text(title, style: Theme.of(context).textTheme.caption),
           SizedBox(
             width: 12.0,
           ),
           Expanded(
             child: Text(
               value,
               style: Theme.of(context)
                   .textTheme
                   .caption
                   .apply(color: Colors.black),
               softWrap: true,
             ),
           ),
         ],
       ),
     );
   }
 
  ...
 
 
 
  • 手机应用启动后,连接ESP32通过注册的的服务,可以向ESP32发送指令,本示例中手机发送“ON”或“OFF”可以控制ESP32一个管脚的的高低电平。



captcha
    暂无评论